package common

import (
	"context"
	"encoding/json"
	"github.com/gorhill/cronexpr"
	"net/http"
	"time"
)

//定时任务
type Job struct {
	Name     string `json:"name"`     // job name
	Command  string `json:"command"`  //shell 命令
	CronExpr string `json:"cronExpr"` //cron 表达式
}

//任务调度计划
type JobSchedulePlan struct {
	Job      *Job                 //任务
	Expr     *cronexpr.Expression //cron 表达式
	NextTime time.Time            //下次调度时间
}

//http接口response结构
type Response struct {
	Code int         `json:"code"`
	Msg  string      `json:"msg"`
	Data interface{} `json:"data"`
}

//变化事件
type JobEvent struct {
	EventType int //实际类型 save, delete
	Job       *Job
}

//任务执行状态信息
type JobExecuteInfo struct {
	Job        *Job
	PlanTime   time.Time //理论调度时间
	RealTime   time.Time //实际调度时间
	CancelCtx  context.Context
	CancelFunc context.CancelFunc
}

//任务执行结果
type JobExecuteResult struct {
	ExecuteInfo *JobExecuteInfo
	Output      []byte //脚本输出
	Err         error
	StartTime   time.Time //脚本执行的开始时间
	EndTime     time.Time //脚本执行的结束时间
}

//任务执行日志 (支持同时解析json 和 bson)
type JobLog struct {
	JobName      string `json:"jobName" bson:"jobName"`           //任务名
	Command      string `json:"command" bson:"command"`           //命令
	Err          string `json:"err" bson:"err"`                   //错误信息
	Output       string `json:"output" bson:"output"`             //输出
	PlanTime     int64  `json:"planTime" bson:"planTime"`         //计划开始实际
	ScheduleTime int64  `json:"scheduleTime" bson:"scheduleTime"` //任务调度时间
	StartTime    int64  `json:"startTime" bson:"startTime"`       //时间执行时间
	EndTime      int64  `json:"endTime" bson:"endTime"`           //结束时间
}

//批量日志
type LogBath struct {
	Logs []interface{}
}

//日志查询过滤条件
type JogLogFilter struct {
	JobName string `bson:"jobName"` //任务名
}

//日志查询排序条件
type JobLogSort struct {
	StartTime int64 `bson:"startTime"` //任务调度时间
}

//构建 http response 的结构
func BuildResponse(code int, msg string, data interface{}) (resp []byte, err error) {
	response := Response{
		Code: code,
		Msg:  msg,
		Data: data,
	}
	return json.Marshal(response)
}

//设置http response header 并发送数据包
func SendResponse(resp http.ResponseWriter, bytes []byte) {
	//设置返回头
	resp.Header().Set("Content-Type", "application/json;charset=uft-8")
	resp.Write(bytes)
}

//构建jobEvent
func BuildJobEvent(eventType int, job *Job) (jobEvent *JobEvent) {
	return &JobEvent{
		EventType: eventType,
		Job:       job,
	}
}

//构建任务调度计划
func BuildJobSchedulePlan(job *Job) (jobSchedulePlan *JobSchedulePlan, err error) {
	expr, err := cronexpr.Parse(job.CronExpr)
	if err != nil {
		return
	}
	jobSchedulePlan = &JobSchedulePlan{
		Job:      job,
		Expr:     expr,
		NextTime: expr.Next(time.Now()),
	}
	return jobSchedulePlan, nil
}

//构建任务状态信息
func BuildJobExecuteInfo(jobPlan *JobSchedulePlan) (jobExecuteInfo *JobExecuteInfo) {
	cancelCtx, cancelFunc := context.WithCancel(context.TODO())
	jobExecuteInfo = &JobExecuteInfo{
		Job:        jobPlan.Job,
		PlanTime:   jobPlan.NextTime,
		RealTime:   time.Now(),
		CancelCtx:  cancelCtx,
		CancelFunc: cancelFunc,
	}
	return
}
